public class ReadMe {
    /**
     * 2023-3-27 数据库基础
     * 1.创建项目，添加web框架支持，配置tomcat
     * 2.下载按照MySQL
     * 3.按照mysql时，建议全部默认，密码建议用 123456；
     * 4.下载一个桌面管理工具：Navcat sqlYong workbench（自带的）
     * 5.连接桌面工具：
     * 6.创建数据库：
     * 7.数据库语言的分类？
     *      1）数据定义语言
     *      2）数据操作语言
     *      3）数据控制语言
     *      4）数据查询语言
     * 8.mysql不区分大小写
     * 9.CREATE SCHEMA `canyin` ;  -- 数据库创建
     *      -- tables 表
     *      -- canyin理解为Java的项目名称，tables理解为Java的对象：一个对象一般对应一张表
     *      -- views  视图 可以理解为自定义封装的方法 ，查询多表的快捷方式 也可以理解为临时表
     *      -- stored procedures  存储过程   以后建议大家不要使用：禁止使用，为什么不要使用存储过程？
     *      -- functions  函数：少用
     * 10.面试：Java的存储引擎：InnoDB和MyISAM的区别？
     * 11.id指主键：（建议必须有，一般自动自增）唯一，不允许为空
     * 12.id的数据类型建议用int；面试？int和long的区别？为什么我建议用int
     *      int大概在20亿条数据如果无符号位则为40亿条数据
     *      一般情况下，数据表大于500万条或者数据大于2G，会考虑分库分表
     *      int  4个字节
     *      long  8个字节
     * 13.用户名：VARCHAR(45)  字符串  45代表最大可以存45给字符
     * 14.CHAR（45） 字符串  固定长度45个字符
     * 15.TEXT 文本  字符串
     * 16.VARCHAR和CHAR和TEXT的区别？
     *      VARCHAR  字符长度可变动
     *      CHAR 固定长度，一般用于密码，或者其他长度固定的字符（长度大小相差不多的字符）
     *      char 比varchar的查询数据更快
     *      varchar比char节省空间
     *      一般字符太多就用text：一般多余两千
     *      密码一般会加密：加密码过后密码的长度基本一致，所以用char
     * 17.TIMESTAMP()和DATETIME的区别？
     *      timestamp所能存储的时间范围为：
     *      '1970-01-01 00:00:01.000000' 到 '2038-01-19 03:14:07.999999'。
     *      datetime所能存储的时间范围为：
     *      '1000-01-01 00:00:00.000000' 到 '9999-12-31 23:59:59.999999'。
     *      数据类型	MySQL 5.6.4之前需要存储	MySQL 5.6.4之后需要存储
     *      DATETIME	8 bytes	5 bytes + 小数秒存储
     *      TIMESTAMP	4 bytes	4 bytes + 小数秒存储
     * 18.常用数据类型
     *      整数：int  tinyint
     *      小数：decimal(5,2)5个有效数字，2个小数
     *      字符：固定char，不固定用varchar太长用text
     *      时间：datetime
     *      所有的都可以用varchar
     * 19.创建表的时候，建议统一添加固定的列：
     *      1）id 主键
     *      2）create_time 创建时间
     *      3）update_time 更新时间
     *      4）enable  状态
     *      5）remark  备注
     * 20.创建表
     *  CREATE TABLE `user` (
     *   `id` INT NOT NULL DEFAULT 10000,
     *   `username` VARCHAR(45) NULL,
     *   `password` CHAR(45) NULL,
     *   `sex` VARCHAR(45) NULL DEFAULT '保密',
     *   `phone` CHAR(11) NULL,
     *   `email` VARCHAR(100) NULL,
     *   `address` VARCHAR(100) NULL,
     *   `birthday` DATETIME NULL,
     *   `age` TINYINT(4) NULL DEFAULT 1,
     *   `weight` DECIMAL(5,2) NULL,
     *   `create_time` DATETIME(6) NULL ,
     *   `update_time` DATETIME(6) NULL,
     *   `enable` TINYINT NULL DEFAULT 1,
     *   `remark` VARCHAR(45) NULL DEFAULT '',
     *   PRIMARY KEY (`id`))
     * ENGINE = InnoDB
     * COMMENT = '用户表';
     * 21.删除表：DROP TABLE `user`;
     * 22.修改表：
     *      ALTER TABLE `canyin`.`user`
     *      CHANGE COLUMN `weight` `height` DECIMAL(5,2) NULL DEFAULT NULL ,
     *      CHANGE COLUMN `update_time` `update_time` TIMESTAMP NULL DEFAULT NULL ;
     *
     *      ALTER TABLE `user`
     *      ADD COLUMN `hobby` VARCHAR(45) NULL AFTER `remark`;
     *
     *      ALTER TABLE `user`
     *      CHANGE COLUMN `hobby` `hobby` VARCHAR(45) NULL DEFAULT NULL AFTER `weight`;
     * 23.总结数据库的创建和表的创建
     *      记关键字：create database `数据库名称`
     *      记关键字：create schema `数据库名称`
     *      用`标记的表示忽略关键字
     *      create table `表名` (列)
     * 24.新增一条数据
     *      INSERT INTO `user` (`username`, `password`, `sex`,
     *  `phone`, `email`, `address`,
     *  `birthday`, `age`, `weight`,
     *  `hobby`, `create_time`, `update_time`,
     *  `enable`, `remark`) VALUES
     *  ('1', '1', '1',
     *  '1', '1', '1',
     *  '2022-2-22', '1', '1',
     *  '1', now(), sysdate(),
     *  '1', '1');
     * 25.得到系统时间： now(), sysdate()
     * 26.修改：
     *      UPDATE `user` SET `username` = '3', `password` = '3', `sex` = '3', `phone` = '3', `email` = '3',
     *  `address` = '3', `birthday` = '2022-03-22 ', `age` = '3', `weight` = '3', `hobby` = '3',
     *  `update_time` = now(), `enable` = '3' WHERE (`id` = '10003');
     * 27.删除某一条数据：
     *      DELETE FROM `user` WHERE (`id` = '10004');
     *      删除的时候，以前的数据，起始还在，只不过被保存到另一个地方去了，还可以找回来
     * 28.删除表数据：
     *      truncate  `user` 彻底删除数据，不能找回，不删除表结构
     * 29.删除表：
     *      drop user; 删除表结构
     * 30.数据同步：
     *      在家里面想要用别人的数据？
     *      数据的导出：将数据导出到某个文件
     *      数据的导入：在另一台电脑，将数据导入到数据库
     * 31.给别人设定数据库的访问权限：
     * 32.数据库建表一般遵循三大范式，五大约束；
     */
    /**
     * 2023-3-28 数据库查询
     * 1.算术运算符  SELECT * FROM product where (normal_price+price)>50;
     * 2.别名 ：select normal_price+price as aa from product
     * 3.逻辑运算符：select * from product where price >100  or price<50;
     * 4.between  and：select * from product where price between 50 and 100;
     * 5.select * from product where id in (1,22,33,43,66);
     * 6.select * from product where id not in (1,22,33,43,66);不建议用
     * 7.模糊查询：select * from product where name like '%肉%';
     * 8.索引：目的就是为了查询更快
     * 9.select * from product where name like '%回%肉%';
     * 10.%代表零个或者多个，_代表单个字符
     * 11.select * from product where name regexp '[锅吧香]肉'  []表示取里面的一个字符
     * 12.[0-9] 表示取0-9中的一个数字
     * 13.[^0-9] 表示非0-9中的一个字符
     * 14.排序：select * from product order by name,id desc;
     * 15.分组：group by
     *      select where_show from product group by where_show,name;
     *      group by 右边的条件一定大于等于左边的列
     *      查询的列一定在group by里面包含
     *      select where_show from product
     *      group by where_show
     *      having where_show>2;
     *      having只和group by有关，相当于where条件
     * 16.表一定要做分页，
     *      -- (page-1)*size,size;  第2页,每一页显示3条
     *      select * from product limit 3,3;
     * 17.查询关键字的顺序
     *      select -->from-->where -->group by-->having-->order by -->limit
     * 18.select count(*) from product where price > 50;
     * select max(price) from product;
     * select min(price) from product;
     * select avg(price) from product;
     * select sum(price) from product;
     *
     *
     * select date_format(create_time,'%Y-%m-%d') from product;
     * 19.count(*)和count(1) 和count(id)的区别？
     * 20.select * from product ,cuisine; 笛卡尔积
     * 21.暂时你们建表的时候，如果表和表存在关系，则在要给表里面创建另一个表的列
     *      产品表                             菜系表
     *      id,name ,cuisine_id             id,name,....
     *      不要讲这两个表合并在一起             1，川菜
     *      当对象和对象存在一对一，多对一的时候
     *      在多的地方加一的id
     * 22.交叉查询
     *      select * from product ,cuisine
     *      where product.cuisine_id=cuisine.id;
     *      select * from product p ,cuisine c   where p.cuisine_id=c.id;
     * 22.内连接
     *      -- inner join 内连接
     *      select * from product p
     *      inner join cuisine c
     *      on p.cuisine_id=c.id
     * 23.左连接：
     *      -- 将所有的产品都查询出来，无论和菜系是否关联，有关联的直接关联就好，没有关联，则用null代替：左连接
     * -- 以左边的表为基准，和右边的表关联，如果没有关联的数据，则用null代替
     * select * from product p
     * left join cuisine c
     * on p.cuisine_id=c.id;
     * 24.右连接：
     * select * from product p
     * right join cuisine c
     * on p.cuisine_id=c.id;
     * 25.子查询
     *      select * from
     * (select p.*,c.name cuisine_name from product p
     * left join cuisine c
     * on p.cuisine_id=c.id) aa
     *  where  aa.name like '%肉%';
     * 26.合并查询  union all 就算里面有相同的数据，也会查询出来（不去重）
     * union  去重（去掉重复的数据）
     *       (select * from product where style=1 limit 1)
     *  union all
     *   (select * from product where style=2 limit 2)
     *    union all
     *   (select * from product where style not in (1,2) limit 7);
     * 27.去重：
     *      select  distinct(price)  from product;
     *      select  price  from product group by price;
     * 28.sql注入：有危险
     *   SELECT * FROM canyin04.user where
     *   username ='supeng' or 1='1';
     *   最简单的方式，将条件当作一个整体而不是一个参数进行传递：
     *
     */
    /**
     * 2023-3-29 Java 连接数据库
     * 1.手写一个连接数据库的方式：JDBC的步骤：六大步骤
     * 2.以用户为例：
     *      增加：
     *          1）model  UserModel
     *          2）servlet   五大步骤
     *          3）service   逻辑
     *          4）dao    数据持久层
     *          5）util工具层 JDBC  将数据保存到数据库
     * 3.在项目中大概会设计到哪些图？
     *      1）流程图  用户新增：正常情况下每一个功能都应该有一个流程图
     *      2）类图   要写多少类：包括类的关系，调用，方法名类名都已写好
     *      3）时序图  按照时间写类：按照执行顺序写类
     *      4）用例图  划分功能模块
     *      5）E-R图  分析对象和对象之间的关系
     *              一般用矩形表示对象，椭圆表示属性，用中文，目的就是为了抽象Javabean
     * 4.以后开发的时候，前端，后端，数据库可以并行操作
     * 5.model根据E-R图来
     * 6.servlet add  五大步骤：最后一步用json对象进行传递
     * 7.加载MySQL驱动：Class.forName("com.mysql.cj.jdbc.Driver");
     *      mysql 5.7版本之前不要cj，之后需要带cj
     * 8.PreparedStatement和Statement的区别？
     * -------------------------------------
     * 总结新增：
     *      1）model
     *      2）servlet  五大步骤
     *      3）service
     *      4）dao  封装sql语句，调用JDBC
     *      5）封装JDBC（只做一次）
     * --------------------------------------
     * 9.删除：
     * 10.修改：
     */
    /**
     * 2023-3-30 Java代码封装
     * 1.任何时候，需要对密码进行加密
     * 2.以后密码最好不让他解密
     * 3.查询所有的时候，至少应该有分页
     * 4.就算没有穿第几页或者每一页显示的条数，则应该有默认的第一页和每一页显示10条数据
     * 5.查询所有：
     *      1）model 添加分页的属性
     *      2）servlet  五大步骤
     *      3）service
     *      4）dao   1，封装sql语句 2.解析结果集 3，返回集合
     *      5）JDBC 添加查询的代码
     * 6.查询总条数
     * 7.一般查询总条数和查询所有（分页）在一起
     *      所以，用户在查询所有的时候，除了将数据传递给前端，还要传递总条数给前端
     * 8.servlet里面最好不要放其他逻辑关系，有逻辑放service
     * 9.以后查询的时候建议不要用*；要哪些列直接写
     * 10.正常情况下，一个表应该有六个基础的操作
     *          增加，修改，删除，查询（总条数，总数居，根据id查询）
     * 11.返回给前端的数据类型太多，能不能固定以下：统一格式：共同制定
     * 12.建议不要在Java的属性里面写布尔；
     * 13.如果有很多地方都有共同的方法，则需要提取一个父类？
     * 14.因为每一个子类写的方法代码不一样，则子类会重写父类的方法
     * 15.说明父类的方法写什么代码都没有用？那么父类就应该写抽象类
     * 16.如果父类的方法全是抽象类，则应该将抽象类定义为接口
     * 17.接口的主要目的就是为了让子类必须做某件事情
     * 18.添加service的父类
     * 19.添加dao的父类
     * 20.泛型
     * --------------------------------------
     * 今日任务：Java后台代码的所有增删改查操作
     */
    /**
     * 2023-3-31 Java后台代码优化
     * 菜系：
     * 1.model
     * 2.servlet 五大步骤
     * 3.service
     * 4.dao  1）sql语句2）jdbc调用
     * 注意：
     * 对于service，servlet，model，dao一定是后缀
     * 接口：IClass ，抽象AbstractClass,枚举 EnumClass
     * 5.select * from cuisine where 1=1  问1=1和true的区别？
     * 6.VO 视图对象：页面对象 view object:
     *      一般存在与servlet和service
     *      主要用于接收前端传递到后台的数据
     *      为了和model分开，对于前端来说不需要知道太多
     * 7.DTO 数据传输对象，一般用于Java传递到前端的数据
     * 8.对于dto应该只出现在service和servlet，增加，修改，删除，查询总条数不需要复制为dto
     * ------------------------------------------------
     * 9.以后所有文件（图片，视频，其他文件）都不要直接存放到数据库，查询慢
     * 10.还有一个成本问题：
     * 11.对于前端传递一个文件的时候，Java后台怎么将文件存到服务器？
     * 12.引入文件的jar包
     * 13.创建接收前端的类：FileServlet
     * 14.将out文件里面的内容复制一份到web目录下，
     * -------------------------------------
     *
     *
     */
    /**
     * 2023-4-3 JavaScript基础
     * 1.三层架构：页面控制层，服务逻辑层，数据持久层
     * 2.页面控制层：servlet  五大步骤
     * 3.服务逻辑层：写逻辑代码
     * 4.数据持久层：封装sql和调用数据库操作
     * 5.vo  将前端传递给Java后台的数据进行封装  view object  视图对象
     * 6.dto  将Java数据封装到dto传递到前端  service层进行封装
     * 7.对对象或者集合的数据进行复制：前提条件：属性名相同才能复制成功
     * 8.密码加密：
     * 9.文件上传：
     *      1）前端要传递文件给后台：接口地址：http://localhost:8080/upload
     *      2)Java后台需要接收文件：req进行接收文件：因为文件类型必须是form/data
     *      3)需要对文件进行解析：调用IO自带的封装类ServletFileUpload
     *      4）前端传递的文件，后台需要有一个容器接收：List<FileItem> list=req;
     *      5)需要将list内存文件放入硬盘进行保存：
     *      6）设置保存硬盘的地址：创建文件夹，文件名（可能会出现一样的文件夹名，所以设置唯一文件名）
     *      7）遍历集合，将集合里面的内容放入硬盘路径：item.write(path);
     *      8）因为默认保存到out目录，不安全，所以暂时还需要将out里面的文件复制到web目录下
     *      9）文件复制
     *      10）将保存到硬盘的地址返回给前端：建议用web目录的绝对地址
     *-------------------------------------------------------------------
     *  layui  xadmin
     * x-admin是基于layui写的模板
     * 1.复制X-admin的模板：里面的内容都不要动
     * 2.熟悉模板里面的内容
     * 3.开始做登录页面:
     * 4.复制登录页面到自己的文件
     * 5.验证码制作步骤
     *      1）画一个图片：对背景进行颜色填充
     *      2）设定一个随机的验证码字符
     *      3）画干扰线
     *-----------------------------------------
     * 6.验证码不能在前端做：前端的任何代码不安全，都可以通过代码得到
     * 7.那么需要访问后台： 需要提供一个接口，img src，a href  都是默认get
     * 8.点击刷新验证码其实是再次访问后台，所以需要对img（div）设定监听事件
     * 9. $(obj).attr("src", "/code?aa=" + Math.random());
     *
     */
    /**
     * 2023-4-4 登录逻辑
     * 1.调用后台的接口，ajax
     * 2.前端逻辑：根据后台传递过来的数据进行逻辑处理
     *       if (res.msg == 'error-code') {
     *                         layer.msg('验证码错误，请重新输入', {icon: 1, time: 2000});
     *                     }
     * 3.java后台的逻辑主要在service层
     *      1）判断验证码是否正确
     *      2）将秘密加密
     *      3）vo数据复制到model
     *      4）根据用户名和密码去数据库里面查询
     *      5）根据查询的结果返回不同的DTO
     * 4.上移快捷键：ctrl+shift+方向键上箭头
     * 5.java怎么在其他servlet里面得到数据 session  application
     * 6.前端js怎么在其他页面拿到数据？
     *      session
     *      local
     * 7.日期在很多地方都会用到，如果是Java的话会设计一个工具类，所以js也可以设置一个工具类
     * 8.div的赋值：$("#id).html(value);
     * 9.div的取值：let value=$("#id).html();
     * --------------------
     * 10.日期格式化：写一个工具类
     * 11.设置定时器：
     * ------------------------------------
     * 12.查询数据表格渲染
     *      1.复制表格到html文件<table class="layui-hide" id="table" lay-filter="test"></table>
     *      2.复制js，修改table.render({
     *              1） elem: '#table'
     *              2）修改url，访问后台的地址
     *              3）修改列：
     *      3.如果想要查看后台返回的数据
     * 13.删除：
     *      1)在html里面必须有lay-event
     *      2）在js里面提示：layer.confirm('真的删除行么'）
     *      3）调用ajax删除数据
     *
     */
    /**
     * 2023-4-6 用户新增和编辑
     * 1.页面之间相互传值
     * 2.js日期格式化
     * 3.用户查询：
     *      1）有页面：复制的table
     *      2）需要复制编辑和删除的代码
     *      3）创建查询的js：
     *          1：页面加载完成执行里面的代码
     *          2：加载layui的模块
     *          3：表格渲染：
     *              1，修改elem
     *              2，修改url
     *              3，将后台的数据打印出来
     *              4，修改列
     *              5,修改自定义模板
     * 4.删除：
     *      1.js里面要监听删除按钮table.on('tool(test)', function (obj) {
     *      2.具体监听哪一个按钮：lay-event="del"
     *      3.重新提示用户是否真的要删除？
     *      4.调用Ajax执行后端操作
     *      5.根据后台的返回值结果进行逻辑处理
     *----------------------------------------
     * 5.新增用户：流程图
     *      1）点击添加弹出添加页面
     *      2)修改页面，写适当的信息
     *      3)自定义验证
     *      4）监听提交按钮
     *      5)调用Ajax执行后台
     *      6）根据返回结果处理逻辑
     * 6.编辑流程：
     *      1）点击编辑按钮，弹出编辑页面
     *      2）同时将id传递到编辑页面
     *      3）在编辑页面页面加载完成时，应该根据id查询数据
     *      4）根据查询的数据将值赋值到表单
     *      5）点击修改按钮进行提交修改
     * ---------------------------------
     * 7.赋值：
     *      $("#id").html(""); 对div进行取值赋值
     *      $("#id").val("");对input表单进行取值赋值
     *      $("#id").attr("key","value"); 对div进行属性的取值赋值
     * 8.对多选框的取值赋值
     * 9.对单选框进行赋值
     * 10.在赋值完成后需要做表单再次刷新： form.render();
     * 11.编辑的时候，需要传id到Java后台
     *
     */
    /**
     * 2023-4-7 模糊查询和产品查询
     * 1.模糊查询：就是对查询所有加条件判断？应该有哪些条件？
     * 2.模糊查询思路：
     *      1）页面修改模糊查询的条件
     *      2)监听查询按钮，得到里面的数据
     *      3）将数据传递到Java后台
     *      4)在servlet里面接收数据
     *      5）在dao层拼接sql语句
     * 3.模糊查询的时候，总条数也应该有条件，和模糊查询的条件应该一样
     * --------------------------------------------------------
     * 4.产品：产品查询
     *      1)左侧导航条修改
     *      2)创建页面
     *      3）创建js，并引入到页面
     *      4）js里面加入模板
     */
    /**
     * 2023-4-10 产品新增和文件上传
     * 1.产品查询的时候，对于管理员来说，应该是查询所有，无论产品是否有对于的菜系
     * 2.在加载产品查询页面的时候，应该将产品菜系加载到下拉菜单
     * 3.产品新增
     *      1)有产品新增页面
     *          1:得到菜系div
     *          2：文件上传的div
     *          3：富文本的div
     *      2)创建新增的js
     *          1）$(function () {
     *          2） layui.use(['form', 'upload', 'element', 'layer']
     *          3）getCuisineName();
     *          4）var uploadInst = upload.render({
     *          5)监听提交按钮，得到保存数据
     *          6）调用ajax传递数据到后台进行保存
     *          7)富文本
     *----------------------------------------------------
     * 产品编辑：
     *      1）创建编辑页面
     *      2）点击编辑时，将id传递到编辑页面
     *      3）编辑页面加载的时候，需要先加载下来菜单
     *      4）加载完下拉菜单后，根据id查询产品
     *      5）查询产品后，将值赋值给表单
     *      6）得到表单的值，注意，需要赋值一个id
     *      7）调用后台的ajax
     */
    /**
     * 2023-4-11 富文本和session认证
     * 1.新增：
     *      1）点击新增按钮弹出新增页面
     *      2）新增页面加载完成需要查询菜系，并将所有符合菜系的内容显示在下拉菜单
     *      3）文件上传的js：
     *      4）富文本的js
     *      5）自定义验证：
     *      6）得到表单的值：
     * 2.编辑产品
     * 3.富文本：注意：将let layedit;
     *                  let index;放在最上面
     * 4.wangeditor的富文本
     * 5.session安全认证
     *      对于用户不登陆也可以访问页面不安全
     *      或在可以直接访问接口也不安全
     *      1)对于前端页面来说，每一次访问页面的时候都去判断一下当前用户是否已经登录
     *        既然每个页面都要去做，我们可以用一个公共的js判断
     *        在页面加载时，判断，而不是加载完成时判断
     *        let username = sessionStorage.getItem("username");
     *          if (username == null) {
     *              window.open("/html/login.html", '_top');
     *          }
     *      2)对于后台接口：Java后台有没有一个直接每次访问的时候也去判断是否已经登录？
     *       过滤器
     *       1：用户登录成功以后同样需要设定登录成功的标识符
     *       req.getSession().setAttribute("username", username);
     *       2:通过过滤器判断
     * 6.对于公用的ajax可以提取公共的js  ajax.js 每一个页面都去引入它
     * 7.注意：myAjax里面的代码需要添加异步关闭
     *  $.ajax({
     *         url: url,
     *         data: data,
     *         dataType: 'json',
     *         type: type,
     *         async: false,
     *         success: function (res) {
     *             result = res;
     *         }
     *     })
     * ---------------------------------------------
     * 第四阶段验收标准：查看word文档验收标准
     *
     */
}
